import React, { createContext, useContext, useState } from 'react';
import IndexPage from '../pages/index/IndexPage';
import LoginPage from '../pages/login/LoginPage';
import { BrowserRouter, Redirect, Route, Switch } from 'react-router-dom';
import HomePage from '../pages/home/HomePage';
import DefaultPage from '../pages/default/DefaultPage';
import GopherProps from '../objects/internal/GopherProps';
import Gopher from '../tooling/Gopher';

const authContext = createContext<{ username: string, login: (user: string, password: string, cb: (success: boolean) => unknown) => void, logout: (cb: () => unknown) => void }>({
	username: '',
	login: () => {
	},
	logout: () => {
	},
});

function useProvideAuth(gopher: Gopher) {
	const [username, setUsername] = useState('');

	const login = (user: string, password: string, cb: (success: boolean) => unknown) => {
		gopher.login(user, password).then(result => {
			if (result) {
				setUsername(user);
			}
			cb(result);
		});
	};

	const logout = (cb: () => unknown) => {
		// TODO
		gopher.logout().then(() => {
			setUsername('');
			cb();
		});
	};

	return {
		username: username,
		login,
		logout,
	};
}

function ProvideAuth({gopher, children}: { gopher: Gopher, children: JSX.Element }) {
	const auth = useProvideAuth(gopher);
	return (
		<authContext.Provider value={auth}>
			{children}
		</authContext.Provider>
	);
}

export function useAuth() {
	return useContext(authContext);
}

// @ts-ignore
function PrivateRoute({children, ...rest}) {
	let auth = useAuth();
	return (
		<Route
			{...rest}
			render={({location}) =>
				auth.username ? (
					children
				) : (
					<Redirect
						to={{
							pathname: '/login',
							state: {from: location},
						}}
					/>
				)
			}
		/>
	);
}

export default function BasicRouter(props: GopherProps) {
	return (
		<ProvideAuth gopher={props.gopher}>
			<BrowserRouter>
				<Switch>
					<Route exact path={'/'} component={IndexPage}/>
					<Route exact path={'/login'}>
						<LoginPage gopher={props.gopher}/>
					</Route>
					<PrivateRoute path={'/home'}>
						<HomePage gopher={props.gopher}/>
					</PrivateRoute>

					<Route path={'*'} component={DefaultPage}/>
				</Switch>
			</BrowserRouter>
		</ProvideAuth>
	);
}
